//
//  ViewController.m
//  Test
//
//  Created by mac on 2017/7/21.
//  Copyright © 2017年 mac. All rights reserved.
//

#import "ViewController.h"
#import <QuartzCore/QuartzCore.h>
#import "ReflectionView.h"

#import <GLKit/GLKit.h>
#import <AVFoundation/AVFoundation.h>
//#import <OpenGLES/opengles.h>
@interface ViewController ()<CALayerDelegate,CAAnimationDelegate>{
    
    CALayer *_testLayer;
}



@property (nonatomic, strong) UIView *glView;
@property (nonatomic, strong) EAGLContext *glContext;
@property (nonatomic, strong) CAEAGLLayer *glLayer;
@property (nonatomic, assign) GLuint framebuffer;
@property (nonatomic, assign) GLuint colorRenderbuffer;
@property (nonatomic, assign) GLint framebufferWidth;
@property (nonatomic, assign) GLint framebufferHeight;
@property (nonatomic, strong) GLKBaseEffect *effect;




@property (nonatomic, weak) IBOutlet UIView *layerView;
@property (nonatomic, strong) CALayer *blueLayer;

//cg开头的，不是cocoa对象，虽然引用释放跟nsobject相似，但是不支持strong来进行强引用。用assign引用
@property (assign, nonatomic) CGImageRef *model;


@property (nonatomic, weak) IBOutlet UIView *layerView1;
@property (nonatomic, weak) IBOutlet UIView *layerView2;

@property (weak, nonatomic) IBOutlet UIView *containView;


@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    

 
 
 
         
   
    
}



     
     

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
    [super touchesBegan:touches withEvent:event];
    [self keyframeAnimationChange];
    
    UIView *view = [self.view viewWithTag:10];
    NSLog(@"%@",NSStringFromCGRect(view.frame));
//    self.view.transform = CGAffineTransformIdentity;
 
}

//“因为Core Animation并不支持自动大小和自动布局”


//CALayer与contentMode对应的属性叫做contentsGravity
//contentsRect，和bounds，frame不同，contentsRect不是按点来计算的，它使用了单位坐标
//contentsCenter，不过这名字着实误导了你。contentsCenter其实是一个CGRect，它定义了一个固定的边框和一个在图层上可拉伸的区域
//contentsRect

//“我们既然可以在3D场景下旋转图层，那么也可以从背面去观察它”
//“图层是双面绘制的，反面显示的是正面的一个镜像图片”
//“CALayer有一个叫做doubleSided的属性来控制图层的背面是否要被绘制”


//矩阵
//“UIView的transform属性是一个CGAffineTransform类型，用于在二维空间做旋转，缩放和平移”
//CALayer同样也有一个transform属性，但它的类型是CATransform3D，而不是CGAffineTransform,他也有一个属性affineTransform是属于CGAffineTransform的

//如果需要混合两个已经存在的变换矩阵，就可以使用如下方法，在两个变换的基础上创建一个新的变换
//CGAffineTransformConcat(CGAffineTransform t1, CGAffineTransform t2);

//“CGAffineTransform类型属于Core Graphics框架，Core Graphics实际上是一个严格意义上的2D绘图API，并且CGAffineTransform仅仅对2D变换有效”

//“X轴和Y轴比较熟悉了，分别以右和下为正方向”“Z轴和这两个轴分别垂直”
//CATransform3D的透视效果通过一个矩阵中一个很简单的元素来控制：m34。m34用于按比例缩放X和Y的值来计算到底要离视角多远
//m34为-1.0 / d来应用透视效果，d代表了想象中视角相机和屏幕之间的距离，以像素为单位”“概估算一个就好了”“通常500-1000就已经很好了


//“Core Animation定义了这个点位于变换图层的anchorPoint”
//“当改变一个图层的position，你也改变了它的灭点，做3D变换的时候要时刻记住这一点，当你视图通过调整m34来让它更加有3D效果，应该首先把它放置于屏幕中央”“然后通过平移来把它移动到指定位置（而不是直接改变它的position），这样所有的3D图层都共享一个灭点”

//如果有多个视图或者图层，每个都做3D变换，那就需要分别设置相同的m34值，并且确保在变换之前都在屏幕中央共享同一个position
//CALayer有一个属性叫做sublayerTransform。它也是CATransform3D类型，但和对一个图层的变换不同，它影响到所有的子图层
//
//一个视图上面有多个子视图，通过容器视图的透视变换，我们可以保证它们有相同的透视和灭点
//“ CATransform3D perspective = CATransform3DIdentity;
//perspective.m34 = - 1.0 / 500.0;
//self.containerView.layer.sublayerTransform = perspective”//self.containerView是父视图

//CAShapeLayer的优势：
//1.相比于Core Graphics，使用了硬件加速，绘图速度比较快
//2.使用Core Graphics绘图，超出的边界会被裁减掉，但是使用CAShapeLayer的不会被裁减掉。例如使用Core Graphics直接在CALayer上面绘图，超出的部分会被裁减掉
//3.相比于CALayer，使用CAShapeLayer不会创建寄宿图，所以占得的空间比较小
//4.使用CAShapeLayer不会出现像素化的问题。在使用CALayer的寄宿图做3d的转换的时候，就会出现像素化的问题，但是使用CAShapeLayer做3D转化的时候不会有这个问题
//CAShapeLayer与CGPath的关系：CGPath表示图形的形状，然后CAShapeLayer进行绘制

//CATextLayer“使用了Core text，并且渲染得非常快。”
//但是如果我们继承了UIView，那我们就可以重写+layerClass方法使得在创建的时候能返回一个不同的图层子类”
//UIView会在初始化的时候调用+layerClass方法，然后用它的返回类型来创建宿主图层。”

//CATransformLayer,它不能显示它自己的内容。只有当存在了一个能作用域子图层的变换它才真正存在。“CATransformLayer并不平面化它的子图层，所以它能够用于构造一个层级的3D结构

//CAGradientLayer，
//CAGradientLayer的真正好处在于绘制使用了硬件加速”



//CAReplicatorLayer的目的是为了高效生成许多相似的图层”
//instanceCount属性指定了图层需要重复多少次。instanceTransform指定了一个CATransform3D3D变换
//“instanceCount属性指定了图层需要重复多少次。instanceTransform指定了一个CATransform3D3D变换”
//“（这种情况下，下一图层的位移和旋转将会移动到圆圈的下一个点）”
//“变换是逐步增加的，每个实例都是相对于前一实例布局。这就是为什么这些复制体最终不会出现在同意位置上”
//使用CAReplicatorLayer做一个倒影的视图

//CAScrollLayer
//“CAScrollLayer有一个-scrollToPoint:方法，它自动适应bounds的原点以便图层内容出现在滑动的地方”
//“Core Animation并不处理用户输入，所以CAScrollLayer并不负责将触摸事件转换为滑动事件，既不渲染滚动条，也不实现任何iOS指定行为例如滑动反弹”
//“CAScrollLayer有一个-scrollToPoint:方法，它自动适应bounds的原点以便图层内容出现在滑动的地方”
//
//“CATiledLayer为载入大图造成的性能问题提供了一个解决方案：将大图分解成小片然后将他们单独按需载入”

//“CAEmitterLayer是一个高性能的粒子引擎，被用来创建实时例子动画如：烟雾，火，雨等等这些效果。CAEmitterLayer看上去像是许多CAEmitterCell的容器，这些CAEmitierCell定义了一个例子效果.一个CAEmitterCell类似于一个CALayer：它有一个contents属性可以定义为一个CGImage，另外还有一些可设置属性控制着表现和行为”


//当iOS要处理高性能图形绘制，必要时就是OpenGL
//OpenGL提供了Core Animation的基础，它是底层的C接口，直接和iPhone，iPad的硬件通信，极少地抽象出来的方法
//OpenGL没有对象或是图层的继承概念。它只是简单地处理三角形。OpenGL中所有东西都是3D空间中有颜色和纹理的三角形
//“Core Animation中只有一些类型的内容是被高度优化的。所以可能找不到合适的图层类去描述你想要描述的东西，这时候追求高性能比较难
//利用OpenGL，你可以绘制任何你知道必要的集合信息和形状逻辑的内容。所以很多游戏都喜欢用OpenGL（这些情况下，Core Animation的限制就明显了：它优化过的内容类型并不一定能满足需求），但是这样依赖，方便的高度抽象接口就没了”

//苹果引入了一个新的框架叫做GLKit，它去掉了一些设置OpenGL的复杂性，提供了一个叫做CLKView的UIView的子类，帮你处理大部分的设置和绘制工作。前提是各种各样的OpenGL绘图缓冲的底层可配置项仍然需要你用CAEAGLLayer完成，它是CALayer的一个子类，用来显示任意的OpenGL图形”



//AVPlayerLayer是用来在iOS上播放视频的。他是高级接口例如MPMoivePlayer的底层实现，提供了显示视频的底层控制”
//事务实际上是Core Animation用来包含一系列属性动画集合的机制，任何用指定事务去改变可以做动画的图层属性都不会立刻发生变化，而是当事务一旦提交的时候开始用一个动画过渡到新值。
//事务是通过CATransaction类来做管理，CATransaction没有属性或者实例方法，并且也不能用+alloc和-init方法创建它。但是可以用+begin和+commit分别来入栈或者出栈。任何可以做动画的图层属性都会被添加到栈顶的事务，你可以通过+setAnimationDuration:方法设置当前事务的动画时间，或者通过+animationDuration方法来获取值”
//Core Animation在每个run loop周期中自动开始一次新的事务（run loop是iOS负责收集用户输入，处理定时器或者网络事件并且重新绘制屏幕的东西），即使你不显式的用[CATransaction begin]开始一次事务，任何在一次run loop循环中属性的改变都会被集中起来，然后做一次0.25秒的动画。”“我们当然可以用当前事务的+setAnimationDuration:方法来修改动画时间，但在这里我们首先起一个新的事务，于是修改时间就不会有别的副作用。因为修改当前事务的时间可能会导致同一时刻别的动画（如屏幕旋转），所以最好还是在调整动画之前压入一个新的事务”

//CATransaction的+begin和+commit方法在+animateWithDuration:animations:内部自动调用，这样block中所有属性的改变都会被事务所包含

//基于UIView的block的动画允许你在动画结束的时候提供一个完成的动作。CATranscation接口提供的+setCompletionBlock:”

//“Core Animation通常对CALayer的所有属性（可动画的属性）做动画，但是UIView把它关联的图层的这个特性关闭了”。例如我们改变一个不是直接跟view关联的layer的背景色时候。会有一个过渡效果，但是如果改变一个跟view直接关联的layer的背景色时候，背景色的改变是没有动画的过渡效果的
//“我们把改变属性时CALayer自动应用的动画称作行为，当CALayer的属性被修改时候，它会调用-actionForKey:方法，传递属性的名称。”
//“图层首先检测它是否有委托，并且是否实现CALayerDelegate协议指定的-actionForLayer:forKey方法。如果有，直接调用并返回结果。
//如果没有委托，或者委托没有实现-actionForLayer:forKey方法，图层接着检查包含属性名称对应行为映射的actions字典。
//如果actions字典没有包含对应的属性，那么图层接着在它的style字典接着搜索属性名。
//最后，如果在style里面也找不到对应的行为，那么图层将会直接调用定义了每个属性的标准行为的-defaultActionForKey:方法。”
//“一轮完整的搜索结束之后，-actionForKey:要么返回空（这种情况下将不会有动画发生），要么是CAAction协议对应的对象，最后CALayer拿这个结果去对先前和当前的值做动画。”
//“于是这就解释了UIKit是如何禁用隐式动画的：每个UIView对它关联的图层都扮演了一个委托，并且提供了-actionForLayer:forKey的实现方法。当不在一个动画块的实现中，UIView对所有图层行为返回nil，但是在动画block范围之内，它就返回了一个非空值”
//“当属性在动画块之外发生改变，UIView直接通过返回nil来禁用隐式动画。但如果在动画块范围之内，根据动画具体类型返回相应的属性”
//[CATransaction setDisableActions:YES];//也可以禁止所有的隐士动画


//“UIView关联的图层禁用了隐式动画，对这种图层做动画的唯一办法就是使用UIView的动画函数（而不是依赖CATransaction），或者继承UIView，并覆盖-actionForLayer:forKey:方法，或者直接创建一个显式动画（因为这个方法，返回的是CABaseAnimation动画）”
//“对于单独存在的图层，我们可以通过实现图层,的-actionForLayer:forKey:委托方法，或者提供一个actions字典来控制隐式动画”
//_testLayer setActions:<#(NSDictionary<NSString *,id<CAAction>> * _Nullable)#>

//“CATransition响应CAAction协议，并且可以当做一个图层行为就足够了”
//“属性动画只对图层的可动画属性起作用，所以如果要改变一个不能动画的属性（比如图片），或者从层级关系中添加或者移除图层，属性动画将不起作用。
//
//于是就有了过渡的概念。过渡并不像属性动画那样平滑地在两个值之间做动画，而是影响到整个图层的变化。过渡动画首先展示之前的图层外观，然后通过一个交换过渡到新的外观”

//但是和属性动画不同的是，对指定的图层一次只能使用一次CATransition，因此，无论你对动画的键设置什么值，过渡动画都会对它的键设置成transition，也就是常量kCATransition。
//CATransision可以对图层任何变化平滑过渡的事实使得它成为那些不好做动画的属性图层行为的理想候选
//
//CATransition并不作用于指定的图层属性，这就是说你可以在即使不能准确得知改变了什么的情况下对图层做动画，例如，在不知道UITableView哪一行被添加或者删除的情况下，直接就可以平滑地刷新它，或者在不知道UIViewController内部的视图层级的情况下对两个不同的实例做过渡动画”
//对图层做截图还是很简单的。CALayer有一个-renderInContext:方法，可以通过把它绘制到Core Graphics的上下文中捕获当前内容的图片，然后在另外的视图中显示出来”

//“在动画过程中取消动画
//“你可以用-addAnimation:forKey:方法中的key参数来在添加动画之后检索一个动画，使用如下方法：
//
//- (CAAnimation *)animationForKey:(NSString *)key;
//但并不支持在动画运行过程中修改动画，所以这个方法主要用来检测动画的属性，或者判断它是否被添加到当前图层中。”
//“为了终止一个指定的动画，你可以用如下方法把它从图层移除掉：
//“- (void)removeAnimationForKey:(NSString *)key;”
//“或者移除所有动画：
//
//- (void)removeAllAnimations;
//“动画一旦被移除，图层的外观就立刻更新到当前的模型图层的值。一般说来，动画在结束之后被自动移除，除非设置removedOnCompletion为NO，如果你设置动画在结束之后不被自动移除，那么当它不需要的时候你要手动移除它；否则它会一直存在于内存中，直到图层被销毁”
//“-animationDidStop:finished:方法中的flag参数表明了动画是自然结束还是被打断，我们可以在控制台打印出来。如果你用停止按钮来终止动画，它会打印NO，如果允许它完成，它会打印YES”
//-(void)animationDidStop:(CAAnimation *)animate finished:(BOOL)flag “委托传入的动画参数animate是原始值的一个深拷贝”

//视图的隐式动画其实CABasicAnimation
//CAKeyframeAnimation：关键帧动画。它和CABasicAnimation作用于单一的一个动画属性。“但是和CABasicAnimation不一样的是，它不限制于设置一个起始和结束的值，而是可以根据一连串随意的值来做动画。关键帧的主要意思是，你提供一个关键帧数组，然后剩下的动画衔接就交给系统完成
//“CAKeyframeAnimation并不能自动把当前值作为第一帧（就像CABasicAnimation那样把fromValue设为nil）”

//“我们需要使用一个三次贝塞尔曲线，它是一种使用开始点，结束点和另外两个控制点来定义形状的曲线”
//CAKeyFrameAnimation添加了一个rotationMode的属性。设置它为常量kCAAnimationRotateAuto（清单8.7），图层将会根据曲线的切线自动旋转
//“如果想要对一个物体做旋转的动画，那就需要作用于transform属性，因为CALayer没有显式提供角度或者方向之类的属性”
//CABasicAnimation和CAKeyframeAnimation仅仅作用于单独的属性,而CAAnimationGroup可以把这些动画组合在一起。CAAnimationGroup是另一个继承于CAAnimation的子类，它添加了一个animations数组的属性，用来组合别的动画

//“ CAAnimationGroup *groupAnimation = [CAAnimationGroup animation];
//groupAnimation.animations = @[animation1, animation2];
//groupAnimation.duration = 4.0;
////add the animation to the color layer
//[colorLayer addAnimation:groupAnimation forKey:nil];

//“CAMediaTiming协议定义了在一段动画内用来控制逝去时间的属性的集合，CALayer和CAAnimation都实现了这个协议，所以时间可以被任意基于一个图层或者一段动画的类控制。”
//“duration和repeatCount默认都是0。但这不意味着动画时长为0秒，或者0次，这里的0仅仅代表了“默认”，也就是0.25秒和1次”




//画作一条曲线做运动
-(void)runWithspecialLine{
    
    UIView *view = [self createView];
    //创建运动路径
    UIBezierPath *bezierPath = [UIBezierPath bezierPath];
    [bezierPath moveToPoint:CGPointMake(0, 150)];//
    [bezierPath addCurveToPoint:CGPointMake(300, 150) controlPoint1:CGPointMake(75, 0) controlPoint2:CGPointMake(225, 300)];
    
    //创建图层
    CAShapeLayer *pathLayer = [CAShapeLayer layer];
    pathLayer.path = bezierPath.CGPath;
    pathLayer.fillColor = [UIColor clearColor].CGColor;
    pathLayer.strokeColor = [UIColor redColor].CGColor;
    pathLayer.lineWidth = 3.f;
    [view.layer addSublayer:pathLayer];
    
    //创建飞机图层显示飞机
    CALayer *shipLyer = [CALayer layer];
    shipLyer.frame = CGRectMake(0, 0, 50, 33);
    shipLyer.position = CGPointMake(0, 150);
    shipLyer.contents = (__bridge id)[UIImage imageNamed:@""].CGImage;
    [view.layer addSublayer:shipLyer];
    
    
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
    animation.keyPath = @"position";
    animation.duration = 4;
    animation.path = bezierPath.CGPath;
    animation.rotationMode = kCAAnimationRotateAuto;
    [shipLyer addAnimation:animation forKey:nil];
    
  
    
}

-(void)keyframeAnimationChange{
    
   UIView *grayview = [self createView];
    grayview.backgroundColor = [UIColor whiteColor];
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
    animation.keyPath = @"backgroundColor";
    animation.duration = 2;
    animation.values = @[(__bridge id)[UIColor grayColor].CGColor,(__bridge id)[UIColor redColor].CGColor,(__bridge id)[UIColor blueColor].CGColor,(__bridge id)[UIColor grayColor].CGColor];
    [grayview.layer addAnimation:animation forKey:@"background"];
}
-(void)startAaimateAndStop{
    
    CALayer *layer = [CALayer layer];
    layer.contents = (__bridge id )[UIImage imageNamed:@"plane"].CGImage;
    layer.frame = CGRectMake(100, 100, 50, 33);
    [self.view.layer addSublayer:layer];
    _blueLayer = layer;

    
    UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 200, 100, 40)];
    [btn setTitle:@"更改动画" forState:UIControlStateNormal];
    [self.view addSubview:btn];
    [btn addTarget:self action:@selector(startAaimateAndStopAction:) forControlEvents:UIControlEventTouchUpInside];
    btn.backgroundColor = [UIColor grayColor];
}

-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
    
    if (flag) {
        NSLog(@"完成终止");
    }else{
         NSLog(@"打断终止");
    }
    
}

-(void)startAaimateAndStopAction:(UIButton *)btn{
    
    btn.selected = !btn.selected;
    
    if (btn.selected) {
        
        //动画
        CABasicAnimation *baseanimation = [CABasicAnimation animation];
        baseanimation.keyPath = @"transform.rotation";//transform.rotation
        baseanimation.duration = 2;
        baseanimation.byValue = @(M_PI_2);
        baseanimation.delegate = self;
        [_blueLayer addAnimation:baseanimation forKey:@"layerAnimation"];
        [baseanimation setValue:@"layerAnimation" forKey:@""];
       
        
    }else{
        
         [_blueLayer removeAnimationForKey:@"layerAnimation"];
    }
}

//绘制一个图层的内容(相当于截屏)
-(void)drawASpecialView{
    
    //创建一个基于位图的上下文（context）,并将其设置为当前上下文(context)。参数size为新创建的位图上下文的大小。它同时是由UIGraphicsGetImageFromCurrentImageContext函数返回的图形大小。透明开关，如果图形完全不用透明，设置为YES以优化位图的存储
    
    UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, YES, [UIScreen mainScreen].scale);
    //那个layer需要在当前的上下文绘图
    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
    //获取画好的图
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
    UIView *view = [[UIImageView alloc] initWithImage:img];
    [self.view addSubview:view];
    view.frame = self.view.bounds;
    
    CGFloat red = arc4random()/(float)INT_MAX;
    CGFloat green = arc4random()/(float)INT_MAX;
    CGFloat blue = arc4random()/(float)INT_MAX;
    self.view.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0];
    
    [UIView animateWithDuration:1 animations:^{
        
      CGAffineTransform affineTransform = CGAffineTransformMakeScale(0.1, 0.1);
        affineTransform = CGAffineTransformRotate(affineTransform, M_PI_2);
        view.transform = affineTransform;
        view.alpha = 0;
    } completion:^(BOOL finished) {
        
        [view removeFromSuperview];
    }];
    
   
}

//使用CATransition做颜色的过渡.推进过渡
-(void)transitionWithColor{
    
    UIImage *img = [UIImage imageNamed:@"Image"];
    UIImageView *imgv = [[UIImageView alloc] initWithImage:img];
    [self.view addSubview:imgv];
    imgv.frame = self.view.bounds;
    
    CALayer *layer = [CALayer layer];
    layer.backgroundColor = [UIColor grayColor].CGColor;
    [self.view.layer addSublayer:layer];
    layer.frame = CGRectMake(100, 100, 100, 100);
    
    CATransition *transition = [CATransition animation];
    transition.type = kCATransitionReveal;
    transition.startProgress = 0.3;
    transition.endProgress = 0.8;
    transition.subtype = kCATransitionFromBottom;
    [layer setActions:@{@"backgroundColor":transition}];
    
    CGFloat red = arc4random() / (CGFloat)INT_MAX;
    CGFloat green = arc4random() / (CGFloat)INT_MAX;
    CGFloat blue = arc4random() / (CGFloat)INT_MAX;
    layer.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0].CGColor;
   
}


//简单的测试颜色过渡
-(void)testAnimation{
    
    UIView *view = [self createView];
    UIButton *btn = [UIButton new];
    btn.frame = CGRectMake(20, 20, 50, 50);
    [view addSubview:btn];
    btn.backgroundColor = [UIColor greenColor];
    [btn addTarget:self action:@selector(btnClik:) forControlEvents:UIControlEventTouchUpInside];
    
    _testLayer = [CALayer layer];
    
    _testLayer.backgroundColor = [UIColor redColor].CGColor;
    [self.view.layer addSublayer:_testLayer];
    _testLayer.frame = CGRectMake(100, 200, 100, 100);
    
   id action = [view actionForLayer:view.layer forKey:@"backgroundColor"];
     NSLog(@"----------%@",action);
    [UIView beginAnimations:nil context:nil];
       id action2 = [view actionForLayer:view.layer forKey:@"backgroundColor"];
     NSLog(@"----------%@",action2);//CABasicAnimation--->CAPropertyAnimation : CAAnimation
    [UIView commitAnimations];
   
}

-(void)btnClik:(UIButton *)btn{
    
    btn.superview.backgroundColor = [UIColor yellowColor];

    self.view.layer.backgroundColor = [UIColor greenColor].CGColor;
   
    _testLayer.backgroundColor = [UIColor blueColor].CGColor;
}
-(void)avplayer{
    
    AVPlayer *player = [AVPlayer playerWithURL:[NSURL URLWithString:@"http://192.168.122.131/home/upload/video/20170523/123123123.mp4"]];
    AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
    playerLayer.frame = CGRectMake(50, 100, 200, 200);
    [self.view.layer addSublayer:playerLayer];
    CATransform3D transfrom = CATransform3DIdentity;
    transfrom.m34 = -1/500;
    transfrom = CATransform3DRotate(transfrom, M_PI_4, 1, 1, 0);
    playerLayer.transform = transfrom;
    playerLayer.borderColor = [UIColor redColor].CGColor;
    playerLayer.borderWidth = 2;
    playerLayer.masksToBounds = YES;
    playerLayer.cornerRadius = 5;
    [player play];
}

-(void)caegallayerTest{
    
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(50, 100, 200, 200)];
    self.glView = view;
    view.backgroundColor = [UIColor grayColor];
    [self.view addSubview:view];
    

    //    需要将它设置为当前context，所有的OpenGL ES渲染默认渲染到当前上下文
    //    EAGLContext管理所有使用OpenGL ES进行描绘的状态，命令以及资源信息，要绘制东西，必须要有上下文，跟图形上下文类似。
    //    当你创建一个EAGLContext，你要声明你要用哪个version的API。这里，我们选择OpenGL ES 2.0
    // 指定OpenGL 渲染 API 的版本，目前都使用 OpenGL ES 2.0
    EAGLRenderingAPI api= kEAGLRenderingAPIOpenGLES2;
    // 创建EAGLContext上下文
    self.glContext= [[EAGLContext alloc]initWithAPI:api];
    // 设置为当前上下文，所有的渲染默认渲染到当前上下文
    [EAGLContext setCurrentContext:self.glContext];
    
    //set up layer
    self.glLayer = [CAEAGLLayer layer];
    self.glLayer.frame = self.glView.bounds;
    [self.glView.layer addSublayer:self.glLayer];
    //    kEAGLDrawablePropertyRetainedBacking ：NO (告诉CoreAnimation不要试图保留任何以前绘制的图像留作以后重用)，kEAGLDrawablePropertyColorFormat ：kEAGLColorFormatRGBA8 (告诉CoreAnimation用8位来保存RGBA的值)
    self.glLayer.drawableProperties = @{kEAGLDrawablePropertyRetainedBacking:@NO, kEAGLDrawablePropertyColorFormat: kEAGLColorFormatRGBA8};
    
    //set up base effect
    self.effect = [[GLKBaseEffect alloc] init];
    
    //set up buffers
    //    创建渲染缓冲区.有了上下文，openGL还需要在一块buffer进行描绘，这块buffer就是RenderBuffer
    //    OpenGLES 总共有三大不同用途的color buffer，depth buffer 和 stencil buffer.
    [self setUpBuffers];
    
    //draw frame
    [self drawFrame];
    
    
}

- (void)setUpBuffers
{
    //set up frame buffer
    glGenFramebuffers(1, &_framebuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer);
    
    //set up color render buffer
    //    它是为renderbuffer(渲染缓存)申请一个id（名字）,创建渲染缓存.数字1代表申请一个renderbuffer
    //    参数renderbuffers返回分配给renderbuffer(渲染缓存)的id
    //     注意：返回的id不会为0，id 0 是OpenGL ES保留的，我们也不能使用id 为0的renderbuffer(渲染缓存)。
    glGenRenderbuffers(1, &_colorRenderbuffer);
    
    //    告诉OpenGL：我在后面引用GL_RENDERBUFFER的地方，其实是引用_colorRenderBuffer
    //    参数target必须为GL_RENDERBUFFER。参数renderbuffer就是使用glGenRenderbuffers生成的id
    glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderbuffer);
    
    //    当指定id的renderbuffer第一次被设置为当前renderbuffer时，会初始化该 renderbuffer对象，其初始值为：
    //    width和height：像素单位的宽和高，默认值为0
    //    internal format：内部格式，三大buffer格式之一-- color，depth orstencil；
    //    Color bit-depth：仅当内部格式为color时，设置颜色的bit-depth，默认值为0；
    //    Depth bit-depth：仅当内部格式为depth时，默认值为0；
    //    Stencil bit-depth: 仅当内部格式为stencil，默认值为0
    
    //    创建帧缓冲区 它相当于buffer(color, depth, stencil)的管理者，三大buffer可以附加到一个framebuffer上
    //    本质是把framebuffer内容渲染到屏幕。是将相关buffer()三大buffer之一)attach到framebuffer上,就会自动把渲染缓存的内容填充到帧缓存，在由帧缓存渲染到屏幕
    //    参数target，哪个帧缓存
    //    参数attachment是指定renderbuffer被装配到那个装配点上，其值是GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT中的一个，分别对应 color，depth和 stencil三大buffer。
    //    renderbuffertarget:哪个渲染缓存
    //    renderbuffer渲染缓存id
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _colorRenderbuffer);
    
    //    把渲染缓存(renderbuffer)绑定到渲染图层(CAEAGLLayer)上，并为它分配一个共享内存
    //    参数target，为哪个renderbuffer分配存储空间
    //    参数drawable，绑定在哪个渲染图层，会根据渲染图层里的绘图属性生成共享内存。
    // 底层调用这个分配内存   glRenderbufferStorage(GL_RENDERBUFFER,GL_RGBA,_openGLLayer.bounds.size.width）
    [self.glContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:self.glLayer];
    
    //    什么是着色器? 通常用来处理纹理对象，并且把处理好的纹理对象渲染到帧缓存上，从而显示到屏幕上。
    //    着色器分为顶点着色器，片段着色器
    //    顶点着色器用来确定图形形状
    //    片段着色器用来确定图形渲染颜色
    //    步骤： 1.编辑着色器代码 2.创建着色器 3.编译着色器
    
    
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &_framebufferWidth);
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &_framebufferHeight);
    
    //check success
    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
        
        NSLog(@"Failed to make complete framebuffer object: %i", glCheckFramebufferStatus(GL_FRAMEBUFFER));
    }
}

- (void)tearDownBuffers
{
    if (_framebuffer) {
        //delete framebuffer
        glDeleteFramebuffers(1, &_framebuffer);
        _framebuffer = 0;
    }
    
    if (_colorRenderbuffer) {
        //delete color render buffer
        glDeleteRenderbuffers(1, &_colorRenderbuffer);
        _colorRenderbuffer = 0;
    }
}

- (void)drawFrame {
    //bind framebuffer & set viewport
    glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer);
    glViewport(0, 0, _framebufferWidth, _framebufferHeight);
    
    //bind shader program
    [self.effect prepareToDraw];
    
    //clear the screen
    glClear(GL_COLOR_BUFFER_BIT); glClearColor(0.0, 0.0, 0.0, 1.0);
    
    //set up vertices
    GLfloat vertices[] = {
        -0.5f, -0.5f, -1.0f, 0.0f, 0.5f, -1.0f, 0.5f, -0.5f, -1.0f,
    };
    
    GLfloat colors[] = {
        0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
    };
    
    //draw triangle
    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glEnableVertexAttribArray(GLKVertexAttribColor);
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 0, vertices);
    
    glVertexAttribPointer(GLKVertexAttribColor,4, GL_FLOAT, GL_FALSE, 0, colors);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    
    //present render buffer
    glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderbuffer);
    [self.glContext presentRenderbuffer:GL_RENDERBUFFER];
}



//多粒子视图
-(void)emitterLayer{
    UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 150, 150)];
    [self.view addSubview:containerView];
    containerView.backgroundColor = [UIColor grayColor];
    
    CAEmitterLayer *layer = [CAEmitterLayer layer];
    layer.frame =containerView.bounds;
    [containerView.layer addSublayer:layer];
    
    //设置属性
    layer.renderMode = kCAEmitterLayerAdditive;
//    The center of the emission shape
    layer.emitterPosition = CGPointMake(layer.frame.size.width/2, layer.frame.size.height/2);
    layer.masksToBounds = YES;
    //设置cell
    CAEmitterCell *cell = [[CAEmitterCell alloc] init];
    cell.contents = (__bridge id)[UIImage imageNamed:@"Image-2"].CGImage;
    cell.birthRate = 50;
    cell.lifetime = 5;
    cell.color = [UIColor colorWithRed:1 green:0.5 blue:0.1 alpha:1.0].CGColor;
    cell.alphaSpeed = -0.4;//每秒速度的变化
    cell.velocity = 50;//初始速度
    cell.velocityRange = 50;
    cell.emissionRange = M_PI;
    
    //设置cell的数量
    layer.emitterCells = @[cell,cell];
    
 
}


//倒影
-(void)reflectionView{
    
    ReflectionView *view = [[ReflectionView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
    [self.view addSubview:view];
    view.backgroundColor = [UIColor grayColor];
    
  
    
}
//重复显示的layer
-(void)replicatorLayerTest{
    
    UIView *view = [UIView new];
    view.frame = self.view.bounds;
    [self.view addSubview:view];
    view.backgroundColor = [UIColor grayColor];
    self.containView = view;
    
    CAReplicatorLayer *repLayer = [CAReplicatorLayer layer];
    repLayer.frame = self.containView.bounds;
    [self.containView.layer addSublayer:repLayer];
    
    //显示10个
    repLayer.instanceCount = 10;
    CATransform3D transform = CATransform3DIdentity;
    transform = CATransform3DTranslate(transform, 0, 200, 0);
    transform = CATransform3DRotate(transform, M_PI/5.0, 0, 0, 1);
    transform = CATransform3DTranslate(transform, 0, -200, 0);
                                       
    
    repLayer.instanceTransform = transform;
    repLayer.instanceBlueOffset = -0.1;
    repLayer.instanceGreenOffset = -0.1;
    
    CALayer *layer = [CALayer layer];
    layer.backgroundColor = [UIColor whiteColor].CGColor;
    layer.frame = CGRectMake(50, 50, 50, 50);
    [repLayer addSublayer:layer];
    
}

//使用CATextLayer显示文字
-(void)showTextWithTextLayer{
    
    UIView *view = [UIView new];
    view.frame = CGRectMake(100, 100, 200, 200);
    [self.view addSubview:view];
    view.backgroundColor = [UIColor grayColor];
    

    CATextLayer *textLayer = [CATextLayer layer];
    textLayer.wrapped = YES;
    textLayer.frame = view.bounds;
    [view.layer addSublayer:textLayer];
    
   UIFont *font = [UIFont systemFontOfSize:15];
    NSLog(@"%@",font.fontName);
    //set layer font
    CFStringRef fontName = (__bridge CFStringRef)font.fontName;
    CGFontRef fontRef = CGFontCreateWithFontName(fontName);
    textLayer.font = fontRef;
    textLayer.fontSize = font.pointSize;
    CGFontRelease(fontRef);
    textLayer.string = @"今天是什么日子啊";
    textLayer.contentsScale = [UIScreen mainScreen].scale;
    CGFontRelease(fontRef);

    
}

-(void)m34Use{
    
    self.view.backgroundColor = [UIColor lightTextColor];
    UIImage *image = [UIImage imageNamed:@"Image-1"];
    UIImageView *imgv = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, image.size.width, image.size.height)];
    imgv.image =image;
    [self.view addSubview:imgv];
    
    CATransform3D transform3d = CATransform3DIdentity;
    transform3d.m34 = -1/900;
    //    transform3d = CATransform3DMakeRotation(M_PI_4, 0, 1, 0);
    transform3d = CATransform3DRotate(transform3d, M_PI_4, 0, 1, 0);
    imgv.layer.transform = transform3d;
}
//缩放旋转平移的组合（缩放平移的顺序会影响最后的结果）
-(void)mixTransform{
    
    
    UIImageView *imgv = [[UIImageView alloc] initWithFrame:CGRectMake(0, 100, 100, 100)];
    imgv.image = [UIImage imageNamed:@"Image-1"];
    [self.view addSubview:imgv];
    
    CGAffineTransform affineForm = CGAffineTransformIdentity;
    CGAffineTransform affineForm1 = CGAffineTransformScale(affineForm, 0.5, 0.5);
    CGAffineTransform  affineForm2 = CGAffineTransformMakeRotation(M_PI/180*30);
    CGAffineTransform affineForm3 =  CGAffineTransformTranslate(affineForm, 200, 0);
    
    CGAffineTransform contact1 = CGAffineTransformConcat(affineForm1, affineForm2);
    CGAffineTransform contact2 = CGAffineTransformConcat(contact1, affineForm3);
    imgv.layer.affineTransform = contact2;
    
    
//    CGAffineTransform transform = CGAffineTransformIdentity; //scale by 50%
//    transform = CGAffineTransformScale(transform, 0.5, 0.5); //rotate by 30 degrees”
//    transform = CGAffineTransformRotate(transform, M_PI / 180.0 * 30.0); //translate by 200 points
//    transform = CGAffineTransformTranslate(transform, 200, 0);
//    //apply transform to layer
//    self.layerView.layer.affineTransform = transform;

  

}

-(void)groupAlph{
    
    //为了设置layer的组透明度一样，需要设置layer的一些属性
    CALayer *layer = [CALayer layer];
    layer.opacity = 0.5;//layer透明度
    layer.shouldRasterize = YES;//解决layer里面，不同的子layer透明度不协调
    layer.rasterizationScale = [UIScreen mainScreen].scale;//“匹配屏幕，以防止出现Retina屏幕像素化的问题。”
    

}
//“CALayer为此提供了三种拉伸过滤方法”
//kCAFilterLinear双性滤波算法。“双线性滤波算法通过对多个像素取样最终生成新的值，得到一个平滑的表现不错的拉伸。但是当放大倍数比较大的时候图片就模糊不清了”

//kCAFilterNearest三性滤波算法，“较双线性滤波算法而言，三线性滤波算法存储了多个大小情况下的图片（也叫多重贴图），并三维取样，同时结合大图和小图的存储进而得到最后的结果。”但是“不要对很多像素同步取样”

//kCAFilterTrilinear最近过滤“。取样最近的单像素点而不管其他的颜色。这样做非常快，也不会使图片模糊。但是，最明显的效果就是，会使得压缩图片更糟，图片放大之后也显得块状或是马赛克严重”

//给view添加一个mask蒙版
-(void)addMaskForView{
    
    UIImage *img = [UIImage imageNamed:@"Image"];
    UIImageView *imgv = [[UIImageView alloc] initWithFrame:self.view.bounds];
    imgv.image = img;
    [self.view addSubview:imgv];
    
    CALayer *layer = [CALayer new];
    layer.frame = CGRectMake(100, 100, 100, 100);
    layer.backgroundColor = [UIColor greenColor].CGColor;
    //    layer.contents = (__bridge id)img.CGImage;
    imgv.layer.mask = layer;
    layer.magnificationFilter = kCAFilterNearest;
//    layer.minificationFilter
}
//复杂阴影设置用UIBezierPath（在CGPath的基础封装的NSObject对象）
-(void)bezierPathWithShadow{
    
}
//CGPath简单的设置自定义阴影
-(void)myShadow{
    
    UIView *layerView1 = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
    [self.view addSubview:layerView1];
    self.layerView1 = layerView1;
    layerView1.backgroundColor = [UIColor greenColor];
    
    UIView *layerView2 = [[UIView alloc] initWithFrame:CGRectMake(250, 100, 100, 100)];
    [self.view addSubview:layerView2];
    self.layerView2 = layerView2;
    layerView2.backgroundColor = [UIColor yellowColor];
    
    
    self.layerView1.layer.shadowOpacity = 0.5f;
    self.layerView2.layer.shadowOpacity = 0.5f;
    
    //create a square shadow
    CGMutablePathRef squarePath = CGPathCreateMutable();
    CGPathAddRect(squarePath, NULL, self.layerView1.bounds);
    self.layerView1.layer.shadowPath = squarePath;CGPathRelease(squarePath);
    
    CGMutablePathRef circle = CGPathCreateMutable();
    CGPathAddEllipseInRect(circle, NULL, layerView2.bounds);
    layerView2.layer.shadowPath = circle;
    CGPathRelease(circle);
}
//设置普通阴影
-(void)layershadow:(CALayer *)layer{
    layer.shadowOpacity = 0.5;//阴影
    layer.shadowOffset = CGSizeMake(2, -4);//x,y轴的偏移
    layer.shadowColor = [UIColor redColor].CGColor;//阴影颜色
    layer.shadowRadius = 4;//模糊度
}

//通过hitTest检测是否包含某个点
-(void)hitTest:(NSSet<UITouch *> *)touches{
    
    CGPoint point = [[touches anyObject] locationInView:self.view];
    CALayer *layer = [self.layerView.layer hitTest:point];
    if (layer == self.layerView.layer) {
        NSLog(@"在灰色");
    }else if(layer == self.blueLayer){
        NSLog(@"在蓝色");
    }
}

//通过坐标转换，containPoint检测是否包含某个点
-(void)converContainPoint:(NSSet<UITouch *> *)touches{
    
    CGPoint point = [[touches anyObject] locationInView:self.view];
    //转化为其他view的坐标
    point = [self.layerView.layer convertPoint:point fromLayer:self.view.layer];
    //判断是否包含
    if ([self.layerView.layer containsPoint:point]) {
        point = [self.blueLayer convertPoint:point fromLayer:self.layerView.layer];
        if ([self.blueLayer containsPoint:point]) {
            NSLog(@"在蓝色");
            
        }else{
            
            NSLog(@"在灰色");
        }
    }
}
//通过设置代理，调用layer的display画图
-(void)draw{
    
    CALayer *layer = [CALayer layer];
    layer.frame = CGRectMake(100, 100, 100, 100);
    [self.view.layer addSublayer:layer];
    layer.backgroundColor = [UIColor grayColor].CGColor;
    layer.delegate = self;
    layer.contentsScale = [UIScreen mainScreen].scale;
    [layer display];
}

//“CALayer创建了一个合适尺寸的空寄宿图（尺寸由bounds和contentsScale决定）和一个Core Graphics的绘制上下文环境，为绘制寄宿图做准备，他作为ctx参数传入”
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx{
    
    //画个圆
    CGContextSetLineWidth(ctx, 10);
    CGContextSetStrokeColorWithColor(ctx, [UIColor redColor].CGColor);
    CGContextStrokeEllipseInRect(ctx, layer.bounds);
    
}

-(UIView *)createView{
    
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(50, 100, 200, 200)];
    self.glView = view;
    view.backgroundColor = [UIColor grayColor];
    [self.view addSubview:view];
    return view;
}
@end
